package naga.x.platform2.app.support;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import naga.x.platform2.utils.StringUtils;


public class JSONTypeHandler<E> extends BaseTypeHandler<E> {
	
	private Class<E> type;
	
	@SuppressWarnings("unchecked")
	public JSONTypeHandler() {
		this((Class<E>) JSONObject.class);
	}
	
	public JSONTypeHandler(Class<E> type) {
		this.type = Objects.requireNonNull(type);
	}

	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
		ps.setString(i, JSON.toJSONString(parameter));
	}

	@Override
	public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
		E obj = parse(rs.getString(columnName));
		if (obj == null && !rs.wasNull()) {
			obj = newInstance();
		}
		return obj;
	}

	@Override
	public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		E obj = parse(rs.getString(columnIndex));
		if (obj == null && !rs.wasNull()) {
			obj = newInstance();
		}
		return obj;
	}

	@Override
	public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		E obj = parse(cs.getString(columnIndex));
		if (obj == null && !cs.wasNull()) {
			obj = newInstance();
		}
		return obj;
	}
	
	E parse(String text) throws SQLException {
		if (StringUtils.isNotEmpty(text)) {
			return JSON.parseObject(text, type);
		}
		return null;
	}
	
	E newInstance() {
		if (!type.isInterface()) {
			try {
				return type.newInstance();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

}
